<?php

namespace app\index\service;

use app\common\model\Member;
use app\index\model\UM as UM;
use ShidianUtil\Concurrent\Synchronizer;
use ShidianUtil\Utils\RandUtil;
use think\exception\ValidateException;

/**
 * Class InviteService
 * @package app\index\service
 */
class InviteService
{

    private Synchronizer $synchronizer;

    public function __construct(Synchronizer $synchronizer)
    {
        $this->synchronizer = $synchronizer;
    }

    /**
     * 查询
     * @param UM $user
     * @return array
     */
    public function read(UM $user): array
    {
        $inviteCode = $user->inviteCode;
        if (is_blank($inviteCode)) {
            $inviteCode = $this->createCode($user->id);
        }

        if (is_blank($inviteCode)) {
            throw new ValidateException('生成邀请码失败，请稍后重试');
        }

        $query = http_build_query([
            'c' => $inviteCode,
        ]);

        $userUrl = 'https://m.xiongmaolvshi.cn/ruser?' . $query;

        $lawyerUrl = 'https://m.xiongmaolvshi.cn/rlawyer?' . $query;

        $yaoyueUrl = 'm.xiongmaolvshi.cn/r/' . $inviteCode;
        $inviteUrlStr = "律师们都在用【熊猫律师】\r\n定向城市每日1000➕精准线索\r\n高效精准获客保证接通\r\n海量付费线索免费获取\r\n「限时免费入驻」\r\n\r\n" . $yaoyueUrl;

        return [
            'inviteCode' => $inviteCode,
            'inviteUrl' => $userUrl,
            'inviteUrl2' => $lawyerUrl,
            'inviteUrlStr' => $inviteUrlStr,
        ];
    }

    /**
     * 生成邀请码
     * @param $id
     * @return null
     */
    private function createCode($id)
    {
        $code = null;

        $signature = InviteService::class . $id;
        $this->synchronizer->synchronized($signature, function () use ($id, &$code) {

            $record = Member::where('id', $id)->find();
            if ($record && is_blank($record->inviteCode)) {

                $result = $this->getAndSaveCode($record, 3);
                if ($result) {
                    $code = $record->inviteCode;
                }
            }
        });

        return $code;
    }

    /**
     * 生成并保存邀请码
     * @param Member $member
     * @param $times
     * @return bool
     */
    private function getAndSaveCode(Member $member, $times): bool
    {
        $code = RandUtil::numberAndLetters(6, false);

        $member->inviteCode = $code;

        try {

            $member->save();

            return true;
        } catch (\Exception $exception) {
            if ($times > 0) {
                return $this->getAndSaveCode($member, $times - 1);
            }

            return false;
        }
    }
}
